package org.ku.hero;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import org.ku.hero.codec.PacketDecoder;
import org.ku.hero.codec.PacketEncoder;
import org.ku.hero.handler.HeartBeatReqHandler;
import org.ku.hero.handler.LoginAuthReqHandler;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class EvNettyClient {
    private static final InternalLogger logger = InternalLoggerFactory.getInstance(EvNettyClient.class);

    public static EvNettyClient instance(){
        return EvNettyClientFactory.SERVER;
    }

    private static class EvNettyClientFactory{
        private static final EvNettyClient SERVER = new EvNettyClient();
    }

    private static final EventLoopGroup bossGroup = new NioEventLoopGroup();
    private static final ScheduledExecutorService executors = Executors.newScheduledThreadPool(1);

    private EvNettyClient(){    }

    public void connect(String ip,int port) throws InterruptedException {
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(bossGroup)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY,true)
                    .handler(new ChannelInitializer<Channel>() {
                        @Override
                        protected void initChannel(Channel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new PacketDecoder(Integer.MAX_VALUE, 4, 4))
                                    .addLast(new PacketEncoder())
                                    .addLast(new ReadTimeoutHandler(50))
                                    .addLast(new HeartBeatReqHandler())
                                    .addLast(new LoginAuthReqHandler());
                        }
                    });

            ChannelFuture future = bootstrap.connect(ip,port).sync();
            logger.info(String.format("【EV数据发送客户端】 %s:%s 连接成功",ip,port));
            future.channel().closeFuture().sync();
        } finally {
            //所有资源释放完成后,清空资源,再次发起重连操作
            executors.execute(()->{
                try {
                    TimeUnit.SECONDS.sleep(5);
                    connect(ip,port);
                }catch (Exception e){
                    e.printStackTrace();
                }
            });
        }

    }

    public void shutdown(){
        if (bossGroup.isTerminated()){
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        EvNettyClient.instance().connect("127.0.0.1",8080);
    }
}
